package com.hxexp.weixin.common.web;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import com.hxexp.weixin.constant.StringConstant;

/**
 * http工具类
 * @author li.jiang
 *
 */
public final class HttpUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(HttpUtil.class);
    private static final String UNKNOW_IP_FLAG = "unknown";

    private HttpUtil() {
    }

    /**
     * 获取POST过来的String数据
     *
     * @param request
     *            HTTP请求
     * @return 请求体中的文本数据
     */
    public static String getStringBody(HttpServletRequest request) {
        StringBuilder sb = new StringBuilder();
        BufferedReader br = null;

        try {
            br = request.getReader();
            String textLine = StringConstant.BLANK;

            while ((textLine = br.readLine()) != null) {
                sb.append(textLine.trim());
            }
            LOGGER.debug("请求体数据:\n{}", sb.toString());
        } catch (IOException ex) {
            LOGGER.error("读取请求BODY数据时发生异常！", ex);
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    LOGGER.error("关闭字符输入流时发生异常！", e);
                }
            }
        }
        return sb.toString();
    }
    /**
     * 获取访问者IP
     *
     * 在一般情况下使用Request.getRemoteAddr()即可，但是经过nginx等反向代理软件后，这个方法会失效。
     *
     * 本方法先从Header中获取X-Real-IP，如果不存在再从X-Forwarded-For获得第一个IP(用,分割)，
     * 如果还不存在则调用Request.getRemoteAddr()
     * @param request http请求
     * @return IP地址
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("X-Real-IP");
        if (!StringUtils.isEmpty(ip) && !UNKNOW_IP_FLAG.equalsIgnoreCase(ip)) {
            return ip;
        }
        ip = request.getHeader("X-Forwarded-For");
        if (!StringUtils.isEmpty(ip) && !UNKNOW_IP_FLAG.equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个IP值，第一个为真实IP。
            int index = ip.indexOf(',');
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        } else {
            return request.getRemoteAddr();
        }
    }
    /**
     * 获取指定文件在服务器上的真实存放路径
     * @param request http请求
     * @param fileContextPath 文件上下文地址(例如：/css/main.css)
     * @return
     */
    public static String getFileRealPath(HttpServletRequest request, String fileContextPath) {
        return request.getSession(true).getServletContext().getRealPath(fileContextPath);
    }

    /**
     * 将request中的参数map转换成查询字符串
     *
     * @param request
     *            http请求
     * @return 查询字符串
     */
    public static String parameterMap2QueryString(HttpServletRequest request) {
        String queryString = "";
        final Map<String, String[]> parameterMap = request.getParameterMap();
        final List<String> parameterList = new ArrayList<String>();

        for(Map.Entry<String, String[]> parameter : parameterMap.entrySet()) {
            String key = parameter.getKey();
            String[] values = parameter.getValue();

            for (int i = 0; i < values.length; i++) {
                try {
                    values[i] = URLEncoder.encode(values[i], "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    LOGGER.error("参数值转码发生异常！", e);
                }
                parameterList.add(String.format("%s=%s", key, values[i]));
            }

        }

        queryString = StringUtils.collectionToDelimitedString(parameterList, "&");

        return queryString;
    }
}
